Completed
Push — master ( 8d2de8...1ce70a )
by Litera
17s
created

netteForms.js ➔ ... ➔ Nette.parseJSON   A

Complexity

Conditions 2
Paths 8

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
cc 2
nc 8
nop 1
rs 9.4285
1
/**
2
 * NetteForms - simple form validation.
3
 *
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7
8
(function(global, factory) {
9
	if (!global.JSON) {
10
		return;
11
	}
12
13
	if (typeof define === 'function' && define.amd) {
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
14
		define(function() {
15
			return factory(global);
16
		});
17
	} else if (typeof module === 'object' && typeof module.exports === 'object') {
18
		module.exports = factory(global);
19
	} else {
20
		var init = !global.Nette || !global.Nette.noInit;
21
		global.Nette = factory(global);
22
		if (init) {
23
			global.Nette.initOnLoad();
24
		}
25
	}
26
27
}(typeof window !== 'undefined' ? window : this, function(window) {
28
29
	'use strict';
30
31
	var Nette = {};
32
33
	Nette.formErrors = [];
34
	Nette.version = '2.4';
35
36
37
	/**
38
	 * Attaches a handler to an event for the element.
39
	 */
40
	Nette.addEvent = function(element, on, callback) {
41
		if (element.addEventListener) {
42
			element.addEventListener(on, callback);
43
		} else if (on === 'DOMContentLoaded') {
44
			element.attachEvent('onreadystatechange', function() {
45
				if (element.readyState === 'complete') {
46
					callback.call(this);
47
				}
48
			});
49
		} else {
50
			element.attachEvent('on' + on, getHandler(callback));
51
		}
52
	};
53
54
55
	function getHandler(callback) {
56
		return function(e) {
57
			return callback.call(this, e);
58
		};
59
	}
60
61
62
	/**
63
	 * Returns the value of form element.
64
	 */
65
	Nette.getValue = function(elem) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
66
		var i;
67
		if (!elem) {
68
			return null;
69
70
		} else if (!elem.tagName) { // RadioNodeList, HTMLCollection, array
71
			return elem[0] ? Nette.getValue(elem[0]) : null;
72
73
		} else if (elem.type === 'radio') {
74
			var elements = elem.form.elements; // prevents problem with name 'item' or 'namedItem'
75
			for (i = 0; i < elements.length; i++) {
76
				if (elements[i].name === elem.name && elements[i].checked) {
77
					return elements[i].value;
78
				}
79
			}
80
			return null;
81
82
		} else if (elem.type === 'file') {
83
			return elem.files || elem.value;
84
85
		} else if (elem.tagName.toLowerCase() === 'select') {
86
			var index = elem.selectedIndex,
87
				options = elem.options,
88
				values = [];
89
90
			if (elem.type === 'select-one') {
91
				return index < 0 ? null : options[index].value;
92
			}
93
94
			for (i = 0; i < options.length; i++) {
95
				if (options[i].selected) {
96
					values.push(options[i].value);
97
				}
98
			}
99
			return values;
100
101
		} else if (elem.name && elem.name.match(/\[\]$/)) { // multiple elements []
102
			var elements = elem.form.elements[elem.name].tagName ? [elem] : elem.form.elements[elem.name],
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable elements already seems to be declared on line 74. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
103
				values = [];
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable values already seems to be declared on line 88. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
104
105
			for (i = 0; i < elements.length; i++) {
106
				if (elements[i].type !== 'checkbox' || elements[i].checked) {
107
					values.push(elements[i].value);
108
				}
109
			}
110
			return values;
111
112
		} else if (elem.type === 'checkbox') {
113
			return elem.checked;
114
115
		} else if (elem.tagName.toLowerCase() === 'textarea') {
116
			return elem.value.replace('\r', '');
117
118
		} else {
119
			return elem.value.replace('\r', '').replace(/^\s+|\s+$/g, '');
120
		}
121
	};
122
123
124
	/**
125
	 * Returns the effective value of form element.
126
	 */
127
	Nette.getEffectiveValue = function(elem) {
128
		var val = Nette.getValue(elem);
129
		if (elem.getAttribute) {
130
			if (val === elem.getAttribute('data-nette-empty-value')) {
131
				val = '';
132
			}
133
		}
134
		return val;
135
	};
136
137
138
	/**
139
	 * Validates form element against given rules.
140
	 */
141
	Nette.validateControl = function(elem, rules, onlyCheck, value, emptyOptional) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
142
		elem = elem.tagName ? elem : elem[0]; // RadioNodeList
143
		rules = rules || Nette.parseJSON(elem.getAttribute('data-nette-rules'));
144
		value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value;
145
146
		for (var id = 0, len = rules.length; id < len; id++) {
147
			var rule = rules[id],
148
				op = rule.op.match(/(~)?([^?]+)/),
149
				curElem = rule.control ? elem.form.elements.namedItem(rule.control) : elem;
150
151
			rule.neg = op[1];
152
			rule.op = op[2];
153
			rule.condition = !!rule.rules;
154
155
			if (!curElem) {
156
				continue;
157
			} else if (rule.op === 'optional') {
158
				emptyOptional = !Nette.validateRule(elem, ':filled', null, value);
159
				continue;
160
			} else if (emptyOptional && !rule.condition && rule.op !== ':filled') {
161
				continue;
162
			}
163
164
			curElem = curElem.tagName ? curElem : curElem[0]; // RadioNodeList
165
			var curValue = elem === curElem ? value : {value: Nette.getEffectiveValue(curElem)},
166
				success = Nette.validateRule(curElem, rule.op, rule.arg, curValue);
167
168
			if (success === null) {
169
				continue;
170
			} else if (rule.neg) {
171
				success = !success;
172
			}
173
174
			if (rule.condition && success) {
175
				if (!Nette.validateControl(elem, rule.rules, onlyCheck, value, rule.op === ':blank' ? false : emptyOptional)) {
176
					return false;
177
				}
178
			} else if (!rule.condition && !success) {
179
				if (Nette.isDisabled(curElem)) {
180
					continue;
181
				}
182
				if (!onlyCheck) {
183
					var arr = Nette.isArray(rule.arg) ? rule.arg : [rule.arg],
184
						message = rule.msg.replace(/%(value|\d+)/g, function(foo, m) {
185
							return Nette.getValue(m === 'value' ? curElem : elem.form.elements.namedItem(arr[m].control));
0 ignored issues
show
Bug introduced by
The variable curElem is changed as part of the for loop for example by curElem.tagName ? curElem: curElem.0 on line 164. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
Bug introduced by
The variable arr is changed as part of the for loop for example by Nette.isArray(rule.arg) ? rule.arg: [rule.arg] on line 183. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
186
						});
187
					Nette.addError(curElem, message);
188
				}
189
				return false;
190
			}
191
		}
192
193
		if (elem.type === 'number' && !elem.validity.valid) {
194
			if (!onlyCheck) {
195
				Nette.addError(elem, 'Please enter a valid value.');
196
			}
197
			return false;
198
		}
199
200
		return true;
201
	};
202
203
204
	/**
205
	 * Validates whole form.
206
	 */
207
	Nette.validateForm = function(sender, onlyCheck) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
208
		var form = sender.form || sender,
209
			scope = false;
210
211
		Nette.formErrors = [];
212
213
		if (form['nette-submittedBy'] && form['nette-submittedBy'].getAttribute('formnovalidate') !== null) {
214
			var scopeArr = Nette.parseJSON(form['nette-submittedBy'].getAttribute('data-nette-validation-scope'));
215
			if (scopeArr.length) {
216
				scope = new RegExp('^(' + scopeArr.join('-|') + '-)');
217
			} else {
218
				Nette.showFormErrors(form, []);
219
				return true;
220
			}
221
		}
222
223
		var radios = {}, i, elem;
224
225
		for (i = 0; i < form.elements.length; i++) {
226
			elem = form.elements[i];
227
228
			if (elem.tagName && !(elem.tagName.toLowerCase() in {input: 1, select: 1, textarea: 1, button: 1})) {
229
				continue;
230
231
			} else if (elem.type === 'radio') {
232
				if (radios[elem.name]) {
233
					continue;
234
				}
235
				radios[elem.name] = true;
236
			}
237
238
			if ((scope && !elem.name.replace(/]\[|\[|]|$/g, '-').match(scope)) || Nette.isDisabled(elem)) {
239
				continue;
240
			}
241
242
			if (!Nette.validateControl(elem, null, onlyCheck) && !Nette.formErrors.length) {
243
				return false;
244
			}
245
		}
246
		var success = !Nette.formErrors.length;
247
		Nette.showFormErrors(form, Nette.formErrors);
248
		return success;
249
	};
250
251
252
	/**
253
	 * Check if input is disabled.
254
	 */
255
	Nette.isDisabled = function(elem) {
256
		if (elem.type === 'radio') {
257
			for (var i = 0, elements = elem.form.elements; i < elements.length; i++) {
258
				if (elements[i].name === elem.name && !elements[i].disabled) {
259
					return false;
260
				}
261
			}
262
			return true;
263
		}
264
		return elem.disabled;
265
	};
266
267
268
	/**
269
	 * Adds error message to the queue.
270
	 */
271
	Nette.addError = function(elem, message) {
272
		Nette.formErrors.push({
273
			element: elem,
274
			message: message
275
		});
276
	};
277
278
279
	/**
280
	 * Display error messages.
281
	 */
282
	Nette.showFormErrors = function(form, errors) {
283
		var messages = [],
284
			focusElem;
285
286
		for (var i = 0; i < errors.length; i++) {
287
			var elem = errors[i].element,
288
				message = errors[i].message;
289
290
			if (!Nette.inArray(messages, message)) {
291
				messages.push(message);
292
293
				if (!focusElem && elem.focus) {
294
					focusElem = elem;
295
				}
296
			}
297
		}
298
299
		if (messages.length) {
300
			alert(messages.join('\n'));
301
302
			if (focusElem) {
303
				focusElem.focus();
304
			}
305
		}
306
	};
307
308
309
	/**
310
	 * Expand rule argument.
311
	 */
312
	Nette.expandRuleArgument = function(form, arg) {
313
		if (arg && arg.control) {
314
			var control = form.elements.namedItem(arg.control),
315
				value = {value: Nette.getEffectiveValue(control)};
316
			Nette.validateControl(control, null, true, value);
317
			arg = value.value;
318
		}
319
		return arg;
320
	};
321
322
323
	var preventFiltering = false;
324
325
	/**
326
	 * Validates single rule.
327
	 */
328
	Nette.validateRule = function(elem, op, arg, value) {
329
		value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value;
330
331
		if (op.charAt(0) === ':') {
332
			op = op.substr(1);
333
		}
334
		op = op.replace('::', '_');
335
		op = op.replace(/\\/g, '');
336
337
		var arr = Nette.isArray(arg) ? arg.slice(0) : [arg];
338
		if (!preventFiltering) {
339
			preventFiltering = true;
340
			for (var i = 0, len = arr.length; i < len; i++) {
341
				arr[i] = Nette.expandRuleArgument(elem.form, arr[i]);
342
			}
343
			preventFiltering = false;
344
		}
345
		return Nette.validators[op]
346
			? Nette.validators[op](elem, Nette.isArray(arg) ? arr : arr[0], value.value, value)
347
			: null;
348
	};
349
350
351
	Nette.validators = {
352
		filled: function(elem, arg, val) {
353
			if (elem.type === 'number' && elem.validity.badInput) {
354
				return true;
355
			}
356
			return val !== '' && val !== false && val !== null
357
				&& (!Nette.isArray(val) || !!val.length)
358
				&& (!window.FileList || !(val instanceof window.FileList) || val.length);
359
		},
360
361
		blank: function(elem, arg, val) {
362
			return !Nette.validators.filled(elem, arg, val);
363
		},
364
365
		valid: function(elem) {
366
			return Nette.validateControl(elem, null, true);
367
		},
368
369
		equal: function(elem, arg, val) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
370
			if (arg === undefined) {
371
				return null;
372
			}
373
374
			function toString(val) {
375
				if (typeof val === 'number' || typeof val === 'string') {
376
					return '' + val;
377
				} else {
378
					return val === true ? '1' : '';
379
				}
380
			}
381
382
			val = Nette.isArray(val) ? val : [val];
383
			arg = Nette.isArray(arg) ? arg : [arg];
384
			loop:
385
			for (var i1 = 0, len1 = val.length; i1 < len1; i1++) {
386
				for (var i2 = 0, len2 = arg.length; i2 < len2; i2++) {
387
					if (toString(val[i1]) === toString(arg[i2])) {
388
						continue loop;
389
					}
390
				}
391
				return false;
392
			}
393
			return true;
394
		},
395
396
		notEqual: function(elem, arg, val) {
397
			return arg === undefined ? null : !Nette.validators.equal(elem, arg, val);
398
		},
399
400
		minLength: function(elem, arg, val) {
401
			if (elem.type === 'number') {
402
				if (elem.validity.tooShort) {
403
					return false;
404
				} else if (elem.validity.badInput) {
405
					return null;
406
				}
407
			}
408
			return val.length >= arg;
409
		},
410
411
		maxLength: function(elem, arg, val) {
412
			if (elem.type === 'number') {
413
				if (elem.validity.tooLong) {
414
					return false;
415
				} else if (elem.validity.badInput) {
416
					return null;
417
				}
418
			}
419
			return val.length <= arg;
420
		},
421
422
		length: function(elem, arg, val) {
423
			if (elem.type === 'number') {
424
				if (elem.validity.tooShort || elem.validity.tooLong) {
425
					return false;
426
				} else if (elem.validity.badInput) {
427
					return null;
428
				}
429
			}
430
			arg = Nette.isArray(arg) ? arg : [arg, arg];
431
			return (arg[0] === null || val.length >= arg[0]) && (arg[1] === null || val.length <= arg[1]);
432
		},
433
434
		email: function(elem, arg, val) {
435
			return (/^("([ !#-[\]-~]|\\[ -~])+"|[-a-z0-9!#$%&'*+\/=?^_`{|}~]+(\.[-a-z0-9!#$%&'*+\/=?^_`{|}~]+)*)@([0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)+[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?$/i).test(val);
436
		},
437
438
		url: function(elem, arg, val, value) {
439
			if (!(/^[a-z\d+.-]+:/).test(val)) {
440
				val = 'http://' + val;
441
			}
442
			if ((/^https?:\/\/((([-_0-9a-z\u00C0-\u02FF\u0370-\u1EFF]+\.)*[0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)?[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-f:]{3,39}\])(:\d{1,5})?(\/\S*)?$/i).test(val)) {
443
				value.value = val;
444
				return true;
445
			}
446
			return false;
447
		},
448
449
		regexp: function(elem, arg, val) {
450
			var parts = typeof arg === 'string' ? arg.match(/^\/(.*)\/([imu]*)$/) : false;
451
			try {
452
				return parts && (new RegExp(parts[1], parts[2].replace('u', ''))).test(val);
453
			} catch (e) {}
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
454
		},
455
456
		pattern: function(elem, arg, val) {
457
			try {
458
				return typeof arg === 'string' ? (new RegExp('^(?:' + arg + ')$')).test(val) : null;
459
			} catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
460
		},
461
462
		integer: function(elem, arg, val) {
463
			if (elem.type === 'number' && elem.validity.badInput) {
464
				return false;
465
			}
466
			return (/^-?[0-9]+$/).test(val);
467
		},
468
469
		'float': function(elem, arg, val, value) {
470
			if (elem.type === 'number' && elem.validity.badInput) {
471
				return false;
472
			}
473
			val = val.replace(' ', '').replace(',', '.');
474
			if ((/^-?[0-9]*[.,]?[0-9]+$/).test(val)) {
475
				value.value = val;
476
				return true;
477
			}
478
			return false;
479
		},
480
481
		min: function(elem, arg, val) {
482
			if (elem.type === 'number') {
483
				if (elem.validity.rangeUnderflow) {
484
					return false;
485
				} else if (elem.validity.badInput) {
486
					return null;
487
				}
488
			}
489
			return arg === null || parseFloat(val) >= arg;
490
		},
491
492
		max: function(elem, arg, val) {
493
			if (elem.type === 'number') {
494
				if (elem.validity.rangeOverflow) {
495
					return false;
496
				} else if (elem.validity.badInput) {
497
					return null;
498
				}
499
			}
500
			return arg === null || parseFloat(val) <= arg;
501
		},
502
503
		range: function(elem, arg, val) {
504
			if (elem.type === 'number') {
505
				if (elem.validity.rangeUnderflow || elem.validity.rangeOverflow) {
506
					return false;
507
				} else if (elem.validity.badInput) {
508
					return null;
509
				}
510
			}
511
			return Nette.isArray(arg) ?
512
				((arg[0] === null || parseFloat(val) >= arg[0]) && (arg[1] === null || parseFloat(val) <= arg[1])) : null;
513
		},
514
515
		submitted: function(elem) {
516
			return elem.form['nette-submittedBy'] === elem;
517
		},
518
519
		fileSize: function(elem, arg, val) {
520
			if (window.FileList) {
521
				for (var i = 0; i < val.length; i++) {
522
					if (val[i].size > arg) {
523
						return false;
524
					}
525
				}
526
			}
527
			return true;
528
		},
529
530
		image: function (elem, arg, val) {
531
			if (window.FileList && val instanceof window.FileList) {
532
				for (var i = 0; i < val.length; i++) {
533
					var type = val[i].type;
534
					if (type && type !== 'image/gif' && type !== 'image/png' && type !== 'image/jpeg') {
535
						return false;
536
					}
537
				}
538
			}
539
			return true;
540
		},
541
542
		'static': function (elem, arg, val) {
0 ignored issues
show
Unused Code introduced by
The parameter val is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
543
			return arg;
544
		}
545
	};
546
547
548
	/**
549
	 * Process all toggles in form.
550
	 */
551
	Nette.toggleForm = function(form, elem) {
552
		var i;
553
		Nette.toggles = {};
554
		for (i = 0; i < form.elements.length; i++) {
555
			if (form.elements[i].tagName.toLowerCase() in {input: 1, select: 1, textarea: 1, button: 1}) {
556
				Nette.toggleControl(form.elements[i], null, null, !elem);
557
			}
558
		}
559
560
		for (i in Nette.toggles) {
561
			Nette.toggle(i, Nette.toggles[i], elem);
562
		}
563
	};
564
565
566
	/**
567
	 * Process toggles on form element.
568
	 */
569
	Nette.toggleControl = function(elem, rules, success, firsttime, value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
570
		rules = rules || Nette.parseJSON(elem.getAttribute('data-nette-rules'));
571
		value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value;
572
573
		var has = false,
574
			handled = [],
575
			handler = function () {
576
				Nette.toggleForm(elem.form, elem);
577
			},
578
			curSuccess;
579
580
		for (var id = 0, len = rules.length; id < len; id++) {
581
			var rule = rules[id],
582
				op = rule.op.match(/(~)?([^?]+)/),
583
				curElem = rule.control ? elem.form.elements.namedItem(rule.control) : elem;
584
585
			if (!curElem) {
586
				continue;
587
			}
588
589
			curSuccess = success;
590
			if (success !== false) {
591
				rule.neg = op[1];
592
				rule.op = op[2];
593
				var curValue = elem === curElem ? value : {value: Nette.getEffectiveValue(curElem)};
594
				curSuccess = Nette.validateRule(curElem, rule.op, rule.arg, curValue);
595
				if (curSuccess === null) {
596
					continue;
597
598
				} else if (rule.neg) {
599
					curSuccess = !curSuccess;
600
				}
601
				if (!rule.rules) {
602
					success = curSuccess;
603
				}
604
			}
605
606
			if ((rule.rules && Nette.toggleControl(elem, rule.rules, curSuccess, firsttime, value)) || rule.toggle) {
607
				has = true;
608
				if (firsttime) {
609
					var oldIE = !document.addEventListener, // IE < 9
610
						name = curElem.tagName ? curElem.name : curElem[0].name,
611
						els = curElem.tagName ? curElem.form.elements : curElem;
612
613
					for (var i = 0; i < els.length; i++) {
614
						if (els[i].name === name && !Nette.inArray(handled, els[i])) {
615
							Nette.addEvent(els[i], oldIE && els[i].type in {checkbox: 1, radio: 1} ? 'click' : 'change', handler);
616
							handled.push(els[i]);
617
						}
618
					}
619
				}
620
				for (var id2 in rule.toggle || []) {
621
					if (Object.prototype.hasOwnProperty.call(rule.toggle, id2)) {
622
						Nette.toggles[id2] = Nette.toggles[id2] || (rule.toggle[id2] ? curSuccess : !curSuccess);
623
					}
624
				}
625
			}
626
		}
627
		return has;
628
	};
629
630
631
	Nette.parseJSON = function(s) {
632
		return (s || '').substr(0, 3) === '{op'
633
			? eval('[' + s + ']') // backward compatibility with Nette 2.0.x
0 ignored issues
show
Security Performance introduced by
Calls to eval are slow and potentially dangerous, especially on untrusted code. Please consider whether there is another way to achieve your goal.
Loading history...
634
			: JSON.parse(s || '[]');
635
	};
636
637
638
	/**
639
	 * Displays or hides HTML element.
640
	 */
641
	Nette.toggle = function(id, visible, srcElement) {
0 ignored issues
show
Unused Code introduced by
The parameter srcElement is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
642
		var elem = document.getElementById(id);
643
		if (elem) {
644
			elem.style.display = visible ? '' : 'none';
645
		}
646
	};
647
648
649
	/**
650
	 * Setup handlers.
651
	 */
652
	Nette.initForm = function(form) {
653
		Nette.toggleForm(form);
654
655
		if (form.noValidate) {
656
			return;
657
		}
658
659
		form.noValidate = true;
660
661
		Nette.addEvent(form, 'submit', function(e) {
662
			if (!Nette.validateForm(form)) {
663
				if (e && e.stopPropagation) {
664
					e.stopPropagation();
665
					e.preventDefault();
666
				} else if (window.event) {
667
					event.cancelBubble = true;
0 ignored issues
show
Bug introduced by
The variable event seems to be never declared. If this is a global, consider adding a /** global: event */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
668
					event.returnValue = false;
669
				}
670
			}
671
		});
672
	};
673
674
675
	/**
676
	 * @private
677
	 */
678
	Nette.initOnLoad = function() {
679
		Nette.addEvent(document, 'DOMContentLoaded', function() {
680
			for (var i = 0; i < document.forms.length; i++) {
681
				var form = document.forms[i];
682
				for (var j = 0; j < form.elements.length; j++) {
683
					if (form.elements[j].getAttribute('data-nette-rules')) {
684
						Nette.initForm(form);
685
						break;
686
					}
687
				}
688
			}
689
690
			Nette.addEvent(document.body, 'click', function(e) {
691
				var target = e.target || e.srcElement;
692
				while (target) {
693
					if (target.form && target.type in {submit: 1, image: 1}) {
694
						target.form['nette-submittedBy'] = target;
695
						break;
696
					}
697
					target = target.parentNode;
698
				}
699
			});
700
		});
701
	};
702
703
704
	/**
705
	 * Determines whether the argument is an array.
706
	 */
707
	Nette.isArray = function(arg) {
708
		return Object.prototype.toString.call(arg) === '[object Array]';
709
	};
710
711
712
	/**
713
	 * Search for a specified value within an array.
714
	 */
715
	Nette.inArray = function(arr, val) {
716
		if ([].indexOf) {
717
			return arr.indexOf(val) > -1;
718
		} else {
719
			for (var i = 0; i < arr.length; i++) {
720
				if (arr[i] === val) {
721
					return true;
722
				}
723
			}
724
			return false;
725
		}
726
	};
727
728
729
	/**
730
	 * Converts string to web safe characters [a-z0-9-] text.
731
	 */
732
	Nette.webalize = function(s) {
733
		s = s.toLowerCase();
734
		var res = '', i, ch;
735
		for (i = 0; i < s.length; i++) {
736
			ch = Nette.webalizeTable[s.charAt(i)];
737
			res += ch ? ch : s.charAt(i);
738
		}
739
		return res.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
740
	};
741
742
	Nette.webalizeTable = {\u00e1: 'a', \u00e4: 'a', \u010d: 'c', \u010f: 'd', \u00e9: 'e', \u011b: 'e', \u00ed: 'i', \u013e: 'l', \u0148: 'n', \u00f3: 'o', \u00f4: 'o', \u0159: 'r', \u0161: 's', \u0165: 't', \u00fa: 'u', \u016f: 'u', \u00fd: 'y', \u017e: 'z'};
743
744
	return Nette;
745
}));
746